<template>
  <view class="gobang-game">
    <!-- 顶部信息栏 -->
    <view class="game-header">
      <view class="current-player">当前: {{currentPlayer === 1 ? '黑棋' : '白棋'}}</view>
      <view class="game-status">{{gameStatus}}</view>
    </view>
    
    <!-- 游戏主区域 -->
    <view class="game-container">
      <canvas 
        class="game-canvas" 
        canvas-id="gobangCanvas"
        :style="{ width: canvasSize + 'px', height: canvasSize + 'px' }"
        @tap="handleBoardClick">
      </canvas>
    </view>
    
    <!-- 控制按钮 -->
    <view class="control-panel">
      <button class="control-btn" @tap="restartGame">重新开始</button>
      <button class="control-btn" @tap="undoMove" :disabled="!canUndo">悔棋</button>
    </view>
  </view>
</template>

<script>
const BOARD_SIZE = 15 // 15x15的棋盘
const CELL_PADDING = 20 // 边距

export default {
  data() {
    return {
      ctx: null,
      board: [], // 棋盘状态
      currentPlayer: 1, // 1为黑棋，2为白棋
      gameStatus: '游戏进行中',
      canvasSize: 300,
      cellSize: 0,
      history: [], // 落子历史
      isGameOver: false
    }
  },
  
  computed: {
    canUndo() {
      return this.history.length > 0 && !this.isGameOver
    }
  },
  
  onLoad() {
    // 初始化画布大小
    const systemInfo = uni.getSystemInfoSync()
    const minSize = Math.min(systemInfo.windowWidth * 0.9, systemInfo.windowHeight * 0.6)
    this.canvasSize = Math.floor(minSize)
    this.cellSize = (this.canvasSize - 2 * CELL_PADDING) / (BOARD_SIZE - 1)
    
    this.initGame()
  },
  
  onReady() {
    this.ctx = uni.createCanvasContext('gobangCanvas', this)
    this.drawBoard()
  },
  
  methods: {
    initGame() {
      // 初始化空棋盘
      this.board = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(0))
      this.currentPlayer = 1
      this.gameStatus = '游戏进行中'
      this.history = []
      this.isGameOver = false
      this.drawBoard()
    },
    
    drawBoard() {
      if (!this.ctx) return
      
      const ctx = this.ctx
      const padding = CELL_PADDING
      
      // 清空画布
      ctx.clearRect(0, 0, this.canvasSize, this.canvasSize)
      
      // 绘制背景
      ctx.setFillStyle('#f3c06c')
      ctx.fillRect(0, 0, this.canvasSize, this.canvasSize)
      
      // 绘制网格
      ctx.setStrokeStyle('#333333')
      ctx.setLineWidth(1)
      
      for (let i = 0; i < BOARD_SIZE; i++) {
        // 横线
        ctx.beginPath()
        ctx.moveTo(padding, padding + i * this.cellSize)
        ctx.lineTo(this.canvasSize - padding, padding + i * this.cellSize)
        ctx.stroke()
        
        // 竖线
        ctx.beginPath()
        ctx.moveTo(padding + i * this.cellSize, padding)
        ctx.lineTo(padding + i * this.cellSize, this.canvasSize - padding)
        ctx.stroke()
      }
      
      // 绘制天元和星位
      const stars = [3, 7, 11]
      stars.forEach(x => {
        stars.forEach(y => {
          ctx.beginPath()
          ctx.arc(
            padding + x * this.cellSize,
            padding + y * this.cellSize,
            3,
            0,
            2 * Math.PI
          )
          ctx.setFillStyle('#333333')
          ctx.fill()
        })
      })
      
      // 绘制棋子
      this.board.forEach((row, y) => {
        row.forEach((cell, x) => {
          if (cell !== 0) {
            this.drawPiece(x, y, cell)
          }
        })
      })
      
      ctx.draw()
    },
    
    drawPiece(x, y, player) {
      const ctx = this.ctx
      const centerX = CELL_PADDING + x * this.cellSize
      const centerY = CELL_PADDING + y * this.cellSize
      
      // 绘制棋子阴影
      ctx.beginPath()
      ctx.arc(centerX + 2, centerY + 2, this.cellSize * 0.4, 0, 2 * Math.PI)
      ctx.setFillStyle('rgba(0,0,0,0.2)')
      ctx.fill()
      
      // 绘制棋子
      ctx.beginPath()
      ctx.arc(centerX, centerY, this.cellSize * 0.4, 0, 2 * Math.PI)
      ctx.setFillStyle(player === 1 ? '#000000' : '#ffffff')
      ctx.fill()
      
      // 白棋加边框
      if (player === 2) {
        ctx.setStrokeStyle('#000000')
        ctx.stroke()
      }
    },
    
    handleBoardClick(e) {
      if (this.isGameOver) return
      
      // Fix the coordinate calculation using createSelectorQuery
      const query = uni.createSelectorQuery().in(this)
      query.select('.game-canvas').boundingClientRect(data => {
        if (!data) {
          console.error('Failed to get canvas position')
          return
        }
        
        const touch = e.changedTouches[0]
        const x = touch.clientX - data.left
        const y = touch.clientY - data.top
        
        // 转换为棋盘坐标
        const boardX = Math.round((x - CELL_PADDING) / this.cellSize)
        const boardY = Math.round((y - CELL_PADDING) / this.cellSize)
        
        // 检查是否在有效范围内
        if (boardX < 0 || boardX >= BOARD_SIZE || boardY < 0 || boardY >= BOARD_SIZE) {
          return
        }
        
        // 检查是否已有棋子
        if (this.board[boardY][boardX] !== 0) {
          return
        }
        
        // 落子
        this.placePiece(boardX, boardY)
      }).exec()
    },
    
    placePiece(x, y) {
      this.board[y][x] = this.currentPlayer
      this.history.push({x, y, player: this.currentPlayer})
      
      // 检查胜负
      if (this.checkWin(x, y)) {
        this.gameStatus = this.currentPlayer === 1 ? '黑棋胜' : '白棋胜'
        this.isGameOver = true
      } else {
        // 切换玩家
        this.currentPlayer = this.currentPlayer === 1 ? 2 : 1
      }
      
      this.drawBoard()
    },
    
    checkWin(x, y) {
      const directions = [
        [1, 0],   // 横向
        [0, 1],   // 纵向
        [1, 1],   // 右下斜
        [1, -1]   // 右上斜
      ]
      
      return directions.some(([dx, dy]) => {
        return this.countLine(x, y, dx, dy) >= 5
      })
    },
    
    countLine(x, y, dx, dy) {
      const player = this.board[y][x]
      let count = 1
      let tempX = x
      let tempY = y
      
      // 向一个方向数
      while (true) {
        tempX += dx
        tempY += dy
        if (!this.isValidPosition(tempX, tempY) || this.board[tempY][tempX] !== player) {
          break
        }
        count++
      }
      
      // 向相反方向数
      tempX = x
      tempY = y
      while (true) {
        tempX -= dx
        tempY -= dy
        if (!this.isValidPosition(tempX, tempY) || this.board[tempY][tempX] !== player) {
          break
        }
        count++
      }
      
      return count
    },
    
    isValidPosition(x, y) {
      return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE
    },
    
    undoMove() {
      if (!this.canUndo) return
      
      const lastMove = this.history.pop()
      this.board[lastMove.y][lastMove.x] = 0
      this.currentPlayer = lastMove.player
      this.gameStatus = '游戏进行中'
      this.isGameOver = false
      this.drawBoard()
    },
    
    restartGame() {
      this.initGame()
    }
  }
}
</script>

<style lang="less">
@import '../../styles/uni.less';

.gobang-game {
  min-height: 100vh;
  background-color: @bg-color;
  padding: @spacing-md;
  
  .game-header {
    display: flex;
    justify-content: space-between;
    padding: @spacing-md;
    background-color: @bg-color-grey;
    border-radius: @border-radius-md;
    margin-bottom: @spacing-lg;
    
    .current-player, .game-status {
      font-size: @font-size-lg;
      color: @text-color;
      font-weight: bold;
    }
  }
  
  .game-container {
    display: flex;
    justify-content: center;
    margin: @spacing-xl 0;
    
    .game-canvas {
      background-color: @bg-color-grey;
      box-shadow: 0 2px 12px rgba(0,0,0,0.1);
      border-radius: @border-radius-md;
    }
  }
  
  .control-panel {
    display: flex;
    justify-content: center;
    gap: @spacing-lg;
    margin-top: @spacing-xl;
    
    .control-btn {
      background-color: @primary-color;
      color: #fff;
      padding: @spacing-sm @spacing-xl;
      border-radius: @border-radius-md;
      font-size: @font-size-md;
      
      &:active {
        opacity: 0.8;
      }
      
      &[disabled] {
        background-color: @bg-color-grey;
        color: @text-color-light;
      }
    }
  }
}
</style>